package org.candan.spider.task.xml;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.ParseException;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.candan.spider.bean.Task;
import org.candan.spider.task.Container;
import org.candan.spider.task.ITaskService;
import org.candan.spider.util.DateUtil;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.dom4j.tree.DefaultElement;


/**
 * 
 *
 */
public class TaskXMLParse extends XMLParseAbstract implements ITaskService  {

//	public PlanXMLParse planPs = new PlanXMLParse();
	private DataSiftParse dfp = new DataSiftParse();
	private  TagSiftParse tfp = new TagSiftParse();
	public  Element root ;
	public  Document document;
	public List<Task> taksLs = new LinkedList<Task>();
	
	
	public TaskXMLParse(){
		init();
	}
	/* (non-Javadoc)
	 * @see org.hdht.business.preproccess.logic.task.TaskOperate#init()
	 */
	@Override
	public void init(){
		getTasks();
		Task task ;
		for(int i = 0; i < root.nodeCount(); i++){
			if(root.node(i) instanceof Element){
				task = xmlToTask((Element)root.node(i));
				//将任务状态为“启动”的任务加载
				if(XMLProperty.STATUS_BEGIN.equals(task.getStatus())){
					Container.tasks.put(task.getId(),task);
					if(!new File(task.getOutput()).exists()){
						new File(task.getOutput()).mkdirs();
					}
				}
			}
		}
	}
	
	

	/**
	 * @category 将xml加载
	 * @param reRead
	 * @return
	 */
	public Element getTasks(boolean... reRead){
		if(root == null  || reRead.length > 0 ){
			document = readXML(XMLProperty.getTaskConfig());
			root = document.getRootElement();
		}
		return root;
	}
	
	/**
	 * @category xml同步控制锁
	 * @param index 1:创建，2：更改  3：删除
	 * @param task
	 */
	synchronized public boolean changeXML(int index, Element el){
		switch(index){
			case 1:
				insertTask(el);
				break;
			case 2:
				updateTask(el);
				break;
			case 3:
				removeTask(el);
				break;
			default: return false;
		}
		serialize(document,XMLProperty.getTaskConfig());
		return true;
	}
	
	
	/**
	 * @category xml增加任务
	 * @param el
	 * @return
	 */
	public Boolean insertTask(Element el){
		root.add(el);
		return true;
	}
	
	/**
	 * @category xml删除任务
	 * @param el
	 */
	public void removeTask(Element el){
//		root.remove(searchElementByID("12323"));
//		root.
//		el.detach();
		root.remove(el);
	}
	
	/**
	 * @category xml更改任务
	 * @param el
	 * @return
	 */
	public Boolean updateTask(Element el){
		root.remove(searchElementByElementID(el));
		insertTask(el);
		return true;
	}
	
	/**
	 * @category xml查询任务
	 * @param id
	 * @return
	 */
	public Element searchElementByID(String id){
		
		return (Element) root.selectSingleNode(XMLProperty.task+"[@id='"+id+"']");
		
	}
	
	/** @category xml查询任务
	 * @param el
	 * @return
	 */
	public Element searchElementByElementID(Element el){
		return searchElementByID(el.attributeValue(XMLProperty.id));
		
	}
	/**
	 * @category Task转换成XML
	 * @param task
	 * @return
	 */
	public Element taskToXML(Task task){
		Element child = null;
		Element el = new DefaultElement(XMLProperty.task);
		
		el.addAttribute(XMLProperty.id, task.getId());
		el.addAttribute(XMLProperty.name, task.getName());
		
		child = new DefaultElement(XMLProperty.status);
		child.addText(task.getStatus());
		el.add(child);

		child = new DefaultElement(XMLProperty.url);
		child.addText(task.getUrl());
		el.add(child);

		child = new DefaultElement(XMLProperty.output);
		child.addText(task.getOutput());
		el.add(child);

		child = new DefaultElement(XMLProperty.startTime);
		child.addText(DateUtil.dateFormat.format(task.getStartTime()));
		el.add(child);

		child = new DefaultElement(XMLProperty.endTime);
		child.addText(DateUtil.dateFormat.format(task.getEndTime()));
		el.add(child);

		
		child = new DefaultElement(XMLProperty.interval);
		Element tmp = new DefaultElement(XMLProperty.type);
		tmp.addText(task.getType());
		child.add(tmp);
		
		tmp = new DefaultElement(XMLProperty.space);
		tmp.addText(task.getSpace());
		child.add(tmp);
		el.add(child);
		
		child = new DefaultElement(XMLProperty.filter);
		if(task.getDatafilter() != null){
			child.add(dfp.dataFilterToXML(task.getDatafilter()));
			
		}
		if(task.getTagFilter() != null){
			child.add(tfp.tagFilterToXML(task.getTagFilter()));
		}
		el.add(child);
		
		return el;
	}
	
	/**
	 * @category xml转换成Task实体类
	 * @param el
	 * @return
	 */
	public Task  xmlToTask(Element el){
		Task task = new Task();
		task.setId(el.attributeValue(XMLProperty.id));
		task.setName(el.attributeValue(XMLProperty.name));
		task.setStatus(selectSingleNodeValue(String.class, el, XMLProperty.status));  
		task.setUrl(selectSingleNodeValue(String.class, el, XMLProperty.url));  
		task.setOutput(selectSingleNodeValue(String.class, el, XMLProperty.output));  
		task.setType(selectSingleNodeValue(String.class, el, XMLProperty.interval+"/"+XMLProperty.type));  
		task.setSpace(selectSingleNodeValue(String.class, el, XMLProperty.interval+"/"+XMLProperty.space)); 
		task.setStartTime(selectSingleNodeValue(Date.class, el, XMLProperty.startTime)) ;
		task.setEndTime(selectSingleNodeValue(Date.class, el, XMLProperty.endTime)) ;
		Node node = el.selectSingleNode(XMLProperty.filter+"/"+XMLProperty.dataFilter);
		if(node != null){
			task.setDatafilter(dfp.xmlToDataFilter((Element) node));
		}
		node = el.selectSingleNode(XMLProperty.filter+"/"+XMLProperty.tagFilter);
		if(node != null){
			task.setTagFilter(tfp.xmlToTagFilger((Element) node));
		}
		setTaskRunInterval(task);
		return task;
	}
	
	/**
	 * @category 任务间隔毫秒
	 * @param task
	 * @return
	 */
	private long setTaskRunInterval(Task task){
		long interval = 0;
		if(XMLProperty.TYPE_HOUR.equals(task.getType().toUpperCase())){
			interval =  (long) (Float.parseFloat(task.getSpace()) * 3600 * 1000);
		}else if(XMLProperty.TYPE_DAY.equals(task.getType().toUpperCase())){
			interval =  (long) (Float.parseFloat(task.getSpace()) * 24 * 3600 * 1000);			
		}else if(XMLProperty.TYPE_WEEK.equals(task.getType().toUpperCase()) ){
			interval =  (long) (Float.parseFloat(task.getSpace()) * 7 * 24 * 3600 * 1000);			
		}
		task.setInterval(interval);
		return interval;
	}
	
	
	
	
	/* (non-Javadoc)
	 * @see org.hdht.business.preproccess.logic.task.TaskAdaperInterface2#searchTaskByID(java.lang.String)
	 */
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println(new TaskXMLParse().selectSingleNodeValue(String.class, null, null));
	}


	@Override
	public void createTask(Task task) {
		// TODO Auto-generated method stub
		changeXML(1,taskToXML(task));
	}

	@Override
	public void deleteTaskByID(String id) {
		// TODO Auto-generated method stub
		changeXML(3, searchElementByID(id));
	}

	@Override
	public void modifyTask(Task task) {
		changeXML(2,taskToXML(task));
	}

	@Override
	public Task searchTaskByID(String id) {
		// TODO Auto-generated method stub
		return xmlToTask(searchElementByID(id));

	}
	@Override
	public List<Task> searchTasks(String... id) {
		List list ;
		if(id.length == 0  || "".equals(id[0])){
			list = root.selectNodes(XMLProperty.task);
		}else{
			list = root.selectNodes(XMLProperty.task+"[@id='"+id+"']");
		}
		if(list.size() != taksLs.size()){
			taksLs.clear();
			Iterator iter = list.iterator();
			Element el = null;
			while (iter.hasNext()) {
				el = (Element) iter.next();
				taksLs.add(xmlToTask(el));
			}

		}
		return taksLs;
	}
	@Override
	public String searchAllTaskXml() {
		// TODO Auto-generated method stub
		return root.asXML();
	}
	


}
